#pragma once
#include "Connection.hpp"
#include <functional>
using func_t = std::function<std::string(std::string&)>;
class IOService : public Connection
{
    static const int num = 1024;

public:
    IOService(int sockfd) : _sockfd(sockfd)
    {
        SetSockfd(sockfd);
        SetEvents(EPOLLIN | EPOLLET);
        // 将fd设置为非阻塞
        SetNonBlock(sockfd);
    }
    virtual void Recv() override
    {
        while (1)
        {
            char buffer[num];
            int n = recv(Sockfd(), buffer, sizeof(buffer) - 1, 0);
            if (n > 0)
            {
                buffer[n] = 0;
                Append(buffer);
            }
            else if (n == 0)
            {
                // 对端关闭连接
                Except();
                break;
            }
            else
            {
                if (errno == EAGAIN)
                {
                    LOG(LogLevel::DEBUG) << "recv处理完所有数据";
                    break;
                }
                else if (errno == EINTR)
                {
                    LOG(LogLevel::DEBUG) << "recv被信号中断，continue";
                    continue;
                }
                else
                {
                    LOG(LogLevel::ERROR) << "recv error";
                    Except();
                    break;
                }
            }
            // 本轮数据读完但不能确保读到的报文是完整的
            std::cout << "inbuf:\n"
                      << InBuf() << std::endl;
            std::string result;
            if (_on_message)
                result = _on_message(InBuf());
            AppendToOut(result);
            // 如何处理将发送缓冲区的数据
            if (!IsOutBufEmpty())
            {
                Send();
                // GetOwner()->EnableReadWrite(_sockfd,true,true);
            }
        }
    }
    virtual void Send() override
    {
        while (1)
        {
            int n = send(_sockfd, OutStr().c_str(), OutStr().size(), 0);
            if (n > 0)
            {
                DisCardOutStr(n);
            }
            else if (n == 0)
            {
                // 缓冲区没有数据了
                break;
            }
            else
            {
                if (errno == EAGAIN)
                {
                    // 缓冲区写满了
                    break;
                }
                else if (errno == EINTR)
                {
                    // 被信号中断
                    continue;
                }
                else
                {
                    LOG(LogLevel::ERROR) << "send error";
                    Except();
                    break;
                }
            }
            // 1.outbuf为空  2.发送缓冲区写满了&&outbuf没有empty
            if (!IsOutBufEmpty())
            {
                GetOwner()->EnableReadWrite(_sockfd, true, true);
            }
            else
            {
                GetOwner()->EnableReadWrite(_sockfd, true, false);
            }
        }
    }
    virtual void Except() override
    {
        LOG(LogLevel::ERROR)<<"出现异常,关闭连接";
        GetOwner()->DelConnection(_sockfd);
    }
    void RegisterOnMessage(func_t on_message)
    {
        _on_message = on_message;
    }

private:
    func_t _on_message;
    int _sockfd;
};